#include <bits/stdc++.h>

#define in read()
#define fi first
#define se second
#define pb push_back

using namespace std;

typedef long long ll;
typedef double db;
typedef vector < int > vec;
typedef pair < int , int > pii;

int read() {
    int x = 0; bool f = 0; char ch = getchar(); while(!isdigit(ch)) f |= ch == '-',ch = getchar();
    while(isdigit(ch)) x = x * 10 + (ch ^ 48),ch = getchar(); return f ? -x : x;
}

const int N = 1e6 + 10;

int n,m;
struct edge { int u,v,w; } e[N << 1];
bool operator < (edge a,edge b) { return a.w < b.w; }

struct dsu {
    int fa[N],siz[N];
    void init() { for(int i = 1;i <= n;i++) fa[i] = i,siz[i] = 1; }
    int gf(int x) { return fa[x] == x ? x : gf(fa[x]); }
    int merge(int x,int y) {
	x = gf(x),y = gf(y); if(x == y) return 0;
	if(siz[x] > siz[y]) swap(x,y); fa[x] = y; siz[y] += siz[x]; return x;
    }
    void undo(int x) { siz[fa[x]] -= siz[x]; fa[x] = x; }
}d;

void Divide(int l,int r,int st) {
    if(l == r) { if(d.siz[d.gf(1)] == n) cout << l << endl,exit(0); return; }
    int mid = l + r >> 1; vec pot;
    for(int i = st;i <= m && e[i].w <= r;i++)
	if(e[i].w > mid) {
	    int p = d.merge(e[i].u,e[i].v); if(p) pot.pb(p);
	}
    Divide(l,mid,st); reverse(pot.begin(),pot.end());
    for(auto x : pot) d.undo(x); vec().swap(pot);
    int pos = st;
    for(int i = st;i <= m;i++)
	if(e[i].w <= mid) {
	    int p = d.merge(e[i].u,e[i].v); if(p) pot.pb(p); pos = i;
	} else break;
    Divide(mid + 1,r,pos + 1); reverse(pot.begin(),pot.end());
    for(auto x : pot) d.undo(x);
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
#endif
    n = in,m = in; for(int i = 1;i <= m;i++) e[i] = (edge) { in , in , in };
    sort(e + 1,e + m + 1); d.init(); Divide(0,e[m].w + 1,1);
    return 0;
}
